package beans;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;
import java.io.Serializable;
import java.util.ArrayList;

public class Forum implements Serializable {
    /** Mitglieder, die nur an Themen lauschen duerfen */
    private PropertyChangeSupport zuhoerer = new PropertyChangeSupport(this);
    /** Mitglieder, die aktiv an Themen teilnehmen duerfen */
    private VetoableChangeSupport entscheider = new VetoableChangeSupport(this);
    /** Titel des Forums */
    private String titel;
    /** Erfolgreich abgestimmte Themen der Mitglieder */
    private ArrayList<String> themen = new ArrayList<>();
    
    /** Zaehlt die Anzahl der Vetos fuer Tests */ 
    private int vetoZaehler = 0;
    
    /**
     * Default-Konstruktor
     */
    public Forum() {
    }
    
    /**
     * Setzt den Titel des Forums
     * @param titel 
     *      neuer Titel
     */
    public void setTitel(String titel) {
        this.titel = titel;
    }
        
    /**
     * Setzt die Themen des Forums
     * @param themen 
     *      neue Themen
     */
    public void setThemen(ArrayList<String> themen) {
        this.themen = themen;
    }
    
    /**
     * Fügt ein neues Thema den vorhanden Themen hinzu.
     * Angemeldete Benutzer werden ueber das neue Thema informiert und koennen
     * ggf. Vetos einlegen.
     * @param thema 
     *      Name des neuen Themas
     */
    public void setThemen(String thema) {
        ArrayList<String> neu = (ArrayList<String>)themen.clone();
        neu.add(thema);

        try {
            entscheider.fireVetoableChange(titel, themen, neu);
            zuhoerer.firePropertyChange(titel, themen, neu);
            this.themen = neu;
        } catch (PropertyVetoException e) {
            System.out.println("Beitrag wurde von "+e.getMessage()+" abgelehnt.");
            vetoZaehler++;
        }
    }
    
    /**
     * Liefert den Titel des Forums
     * @return 
     *      der Titel des Forums
     */
    public String getTitel() {
        return this.titel;
    }
    
    /**
     * Liefert die abgestimmten Themen des Forums
     * @return 
     *      Liste der erfolgreich abgestimmten Themen
     */
    public ArrayList<String> getThemen() {
        return themen;
    }
      
    /**
     * Fuegt einen neuen PropertyChangeListner hinzu.
     * @param l 
     *      neuer Listener
     */
    public void addPropertyChangeListener(PropertyChangeListener l) {
        zuhoerer.addPropertyChangeListener(l);
    }
    
    /**
     * Entfernt einen PropertyChangeListner.
     * @param l 
     *      zu entfernender Listener
     */
    public void removePropertyChangeListener(PropertyChangeListener l) {
        zuhoerer.removePropertyChangeListener(l);
    }
    
    /**
     * Fuegt einen neuen VetoableChangeListner hinzu.
     * @param l 
     *      neuer Listener
     */
    public void addVetoableChangeListener(VetoableChangeListener l) {
        entscheider.addVetoableChangeListener(l);
    }
    
    /**
     * Entfernt einen VetoableChangeListner.
     * @param l 
     *      zu entfernender Listener
     */
    public void removeVetoableChangeListener(VetoableChangeListener l) {
        entscheider.removeVetoableChangeListener(l);
    }

    @Override
    public String toString() {
        StringBuffer str = new StringBuffer("Forum "+titel+'\n');
        
        str.append("Verabschiedet:\n");
        for (String t:themen) {
            str.append(t+'\n');
        }
        
        return str.toString();
    }
    
    PropertyChangeSupport getZuhoerer() {
        return zuhoerer;
    }
    
    VetoableChangeSupport getEntscheider() {
        return entscheider;
    }
    
    PropertyChangeListener[] getZuhoererListener() {
        return zuhoerer.getPropertyChangeListeners();
    }
    
    VetoableChangeListener[] getEntscheiderListener() {
        return entscheider.getVetoableChangeListeners();
    }
    
    public int getVetoZaehler() {
        return vetoZaehler;
    }
}
